<template>
  <page-meta :page-style="'overflow:' + (showSharePopup ? 'hidden' : 'visible')"></page-meta>
  <PageContainer>
    <view class="container">
      <Header title="相册详情" :is-box-shadow="false">
        <template v-if="showUpTips">
          <view class="topTips">
            <text class="ali-icon">{{ upLoading ? '&#xec1d;' : '&#xe631;' }}</text>
            <text>{{ upLoading ? '上传中请勿退出小程序' : '上传成功' }}</text>
          </view>
        </template>
      </Header>

      <view class="bgf">
        <view class="imageBox">
          <TImage
            :src="photoAlbumInfo.coverUrl || photoAlbumInfo.originalCoverUrl"
            width="100%"
            height="fit-content"
            mode="widthFix"
            preview
          />
          <view class="topTag fz-12 px-13 py-4" @click.stop="upCoverImg">更换封面</view>
        </view>
        <view class="timesBox fz-12 linh-39 px-10">
          <text class="pr-20">{{ photoAlbumInfo.publishTime }}</text>
          <text class="ali-icon fz-14">&#xe6cf;</text>
          <text class="ml-8">
            {{ photoAlbumInfo.browseNum ? formatNumber(photoAlbumInfo.browseNum) : 0 }}
          </text>
        </view>
        <!-- 相册名称 -->
        <view class="pb-15 px-10 fz-16 fw-7">
          <input
            v-if="editNameIn"
            :value="photoAlbumInfo.name"
            focus
            placeholder="请输入相册名称"
            @blur="confirmEditName"
          />
          <view v-else @click="toggleEditName" class="textBox">
            <view class="ov-2">
              {{ photoAlbumInfo.name }}
            </view>
            <view class="editText">
              <text class="ali-icon">&#xe8cc;</text>
              <text class="fz-10">编辑</text>
            </view>
          </view>
        </view>
        <!-- 相册描述 -->
        <view class="pb-15 px-10 fz-14">
          <textarea
            v-if="editDescIn"
            :value="photoAlbumInfo.desc"
            focus
            auto-height
            :maxlength="900"
            placeholder="请输入相册描述"
            @blur="confirmEditDesc"
          />
          <view v-else @click="toggleEditDesc" class="textBox">
            <view class="linh-16" style="word-break: break-all">
              <text space="nbsp">
                {{ photoAlbumInfo.desc || '暂无描述~' }}
              </text>
            </view>
            <view class="editText">
              <text class="ali-icon">&#xe8cc;</text>
              <text class="fz-10">编辑</text>
            </view>
          </view>
        </view>
      </view>

      <view class="bgf mt-10">
        <view class="disFlxJS px-10 linh-50 borderBottom">
          <view class="fz-16 fw-7">照片展示</view>
          <view style="color: #aaabab">
            <text class="ali-icon fz-14">&#xe8ba;</text>
            <text class="pl-2 fz-12">{{ imgTotal }}张</text>
          </view>
        </view>
        <Paglist
          v-model="apiData"
          :is-init-api="false"
          :parame="parame"
          @register="register"
          :is-show-loadmore="apiData.length > 1"
        >
          <view class="pr-10 pt-10 disFlxAC imgList">
            <view
              v-for="item in apiData"
              :key="item.id"
              class="br-5 ml-10 mb-10 forImageBox"
              @click="previewPhoto(item)"
            >
              <TImage
                :src="item.url || item.coverUrl"
                width="100%"
                height="100%"
                mode="aspectFill"
              />
              <view v-if="settingIn" class="checkedBox">
                <image
                  v-if="isChecked(item.id)"
                  src="https://hb-saas.obs.cn-south-1.myhuaweicloud.com/mall/saas/icon/radio-checked2.png"
                  style="width: 32rpx; height: 32rpx"
                />
                <image v-else src="https://hb-saas.obs.cn-south-1.myhuaweicloud.com/mall/saas/icon/radio.png" style="width: 32rpx; height: 32rpx" />
              </view>
            </view>
          </view>
        </Paglist>
      </view>

      <TButtonGroup :styles="{ backgroundColor: '#FFF' }">
        <template #header>
          <view v-if="settingIn" class="slotBox">
            <view class="disFlxCC" style="width: 120rpx" @click="batchDwImg">
              <TImage :src="downloadIcon" width="48rpx" height="48rpx" />
              <view class="fz-12">下载</view>
            </view>
            <view class="disFlxCC" style="width: 120rpx" @click="batchDeleteImg">
              <TImage :src="removeIcon" width="48rpx" height="48rpx" />
              <view class="fz-12">删除</view>
            </view>
          </view>
          <view v-else class="slotBox">
            <view class="disFlxCC" style="width: 120rpx" @click="openShare">
              <TImage :src="shareIcon" width="48rpx" height="48rpx" />
              <view class="fz-12">分享</view>
            </view>
            <view class="disFlxCC" style="width: 120rpx" @click="settingImage">
              <TImage :src="imageIcon" width="48rpx" height="48rpx" />
              <view class="fz-12">管理照片</view>
            </view>
            <view class="disFlxCC" style="width: 120rpx" @click="goAddPhotos">
              <TImage :src="settingIcon" width="48rpx" height="48rpx" />
              <view class="fz-12">设置</view>
            </view>
          </view>
        </template>
        <TButton
          v-if="settingIn"
          class="gutter-btn"
          :text="`取消（${checkedIds.length}）`"
          type="primary"
          @click="settingImage"
        />
        <TButton
          v-else
          class="gutter-btn"
          :text="upLoading ? '上传中' : '上传'"
          :disabled="upLoading"
          type="primary"
          @click="openUpFile"
        />
      </TButtonGroup>
    </view>
  </PageContainer>

  <CustomShare
    v-if="photoAlbumInfo"
    v-model:visible="showSharePopup"
    @register="handleCustomShareRegister"
  />
</template>

<script lang="ts" setup>
  /* photosDetails 相册详情 */
  import PageContainer from '@/components/PageContainer/index.vue';
  import Header from '@/components/Header/index.vue';
  import TImage from '@/components/TImage/index.vue';
  import TButtonGroup from '@/components/TButtonGroup/index.vue';
  import TButton from '@/components/TButtonGroup/TButton.vue';
  import { svgToDataUrl } from '@/utils/index';
  import { shareSVG, settingSVG, imageSVG, downloadSvg, removeSvg } from '../components/photosIcon';
  import { navigateTo, onLoad } from '@/router';
  import { provide, reactive, ref, unref, watch } from 'vue';
  import {
    photoAlbumDetails,
    modifyPhotoAlbum,
    addBatchPhoto,
    delBatchPhoto,
  } from '@/api/admin/index';
  import type { BatchUpImageData, PhotosData } from '@/api/admin/types';
  import { FileType, IsTop } from '@/enums/admin';
  import { photoList } from '@/api/photoAlbum';
  import type { PhotoListResult } from '@/api/photoAlbum/types';
  import Paglist from '@/components/Paglist/index.vue';
  import { useConList } from '@/components/Paglist/useConList';
  import { useUpload } from '@/hooks/core/useUpload';
  import { cloneDeep, isEmpty } from 'lodash-es';
  import { logManager } from '@/utils/log';
  import { onShareAppMessage, onShow } from '@dcloudio/uni-app';
  import { createMiniCode } from '@/utils/dynamicConfig';
  import { downloadFiles } from '../components/downloadFiles';
  import { Toast } from '@/utils/index';
  import { useAppShare } from '@/hooks/core/useAppShare';
  import CustomShare from '@/components/CustomShare/index.vue';
  import { useCustomShare } from '@/components/CustomShare/hooks/useCustomShare';
  import { addAppShareLog } from '@/api';
  import { getAlbumPosterData } from '../components/utils';

  const { createShareQuery, setWxSharePath } = useAppShare();

  const showSharePopup = ref(false);
  const [
    customShareRegister,
    { setWxShareOptions, setShareLogId, setPosterDrawData, setInternalLinkOptions },
  ] = useCustomShare({
    buttons: {
      share: true,
      poster: true,
      copyLink: true,
      insertOffiaccount: true,
    },
    disableds: {
      shortLink: true,
    },
  });

  const shareLogId = ref<number>();
  const shareCodeImg = ref<string>();
  async function handleCustomShareRegister(e: any) {
    customShareRegister(e);
    const routeQuery = createShareQuery({ id: id.value });

    const res = await addAppShareLog({
      path: 'photoAlbumDetails',
      query: JSON.stringify(routeQuery),
    });
    setInternalLinkOptions({
      name: 'photoAlbumDetails',
      options: { id: id.value as number },
    });
    shareLogId.value = res.id;
    setShareLogId(res.id);
    shareCodeImg.value = await createMiniCode({ shareLogId: res.id });
    setShareOptions();
  }

  async function setShareOptions() {
    if (!photoAlbumInfo.value) return Promise.resolve(true);
    const { name, originalCoverUrl, coverUrl } = photoAlbumInfo.value;
    const describe = '分享一个相册给你，来看看吧~';
    await setWxShareOptions([
      {
        path: setWxSharePath({ name: 'photoAlbumDetails', options: { id: id.value as number } }),
        imageUrl: originalCoverUrl ?? coverUrl, // 封面
        title: name,
      },
      {
        path: setWxSharePath({ name: 'photoAlbumDetails', options: { id: id.value as number } }),
        imageUrl: originalCoverUrl ?? coverUrl, // 封面
        title: describe,
      },
    ]);

    await setPosterDrawData(
      getAlbumPosterData(
        { name, coverUrl: originalCoverUrl ?? coverUrl, describe },
        shareCodeImg.value as string,
      ),
    );
  }

  const shareIcon = svgToDataUrl(shareSVG);
  const settingIcon = svgToDataUrl(settingSVG);
  const imageIcon = svgToDataUrl(imageSVG);
  const downloadIcon = svgToDataUrl(downloadSvg);
  const removeIcon = svgToDataUrl(removeSvg);

  const id = ref<number>();
  const parame = reactive({ belongId: 0 });
  onLoad(async (op) => {
    id.value = op.id;
    parame.belongId = op.id;
    await __init();
  });
  onShow(async () => {
    if (unref(isPreview)) {
      // 预览图片并关闭时,不刷新列表
      isPreview.value = false;
      return;
    }
  });

  const photoAlbumInfo = ref({} as PhotosData);
  /** 原始数据 */
  const apiData = ref<PhotoListResult[]>([]);
  const imgTotal = ref<number>(0);
  provide('api', async (obj: any) => {
    const r = await photoList(obj);
    imgTotal.value = r.total;
    return r;
  });
  const [register, { refresh }] = useConList();
  async function __init() {
    if (unref(id)) {
      const res = await photoAlbumDetails(unref(id) as number);
      photoAlbumInfo.value = res;
      photoAlbumInfo.value.top = res.sort ? IsTop.YES : IsTop.NO;
      refresh?.();
    }
  }

  // 上传照片
  const { request, result, resetResult, chooseFile } = useUpload({ customTriggerUpload: true });
  const openUpFile = () => {
    chooseFile({ mediaType: 'image' });
  };

  watch(
    result,
    async (val) => {
      const upImgList = cloneDeep(val);
      if (upImgList.length) {
        await upImage(upImgList);
        resetResult();
      }
    },
    { deep: true },
  );

  const upLoading = ref(false);
  const showUpTips = ref(false);
  watch(upLoading, (val) => {
    if (val) {
      showUpTips.value = val;
    } else {
      setTimeout(() => {
        showUpTips.value = val;
      }, 2000);
    }
  });
  async function upImage(upList: any[]) {
    upLoading.value = true;
    try {
      const batchUpList = ref<BatchUpImageData[]>([]);
      for (let i = 0; i < upList.length; i++) {
        const item = upList[i];
        if (item && !item.filePath && item.progress !== 100) {
          const res = await request('image', item);
          item.filePath = res.imagePathBig || res.fileUrl;

          batchUpList.value.push({
            belongId: unref(id) as number,
            coverUrl: item.filePath,
            type: FileType.ISIMAGE,
            name: item.fileName,
            url: item.filePath,
            size: item.fileSize,
          });
        }
      }

      await addBatchPhoto(unref(batchUpList));
      upLoading.value = false;
      refresh?.();
    } catch (error) {
      upLoading.value = false;
      logManager.error(error);
    }
  }

  // 管理照片
  const settingIn = ref(false);
  const checkedIds = ref<number[]>([]);
  const settingImage = () => {
    settingIn.value = !settingIn.value;
    checkedIds.value = [];
  };

  // 判断是否勾选
  const isChecked = (imgId: number) => {
    return checkedIds.value.includes(imgId);
  };
  // 批量下载
  const batchDwImg = () => {
    if (!unref(checkedIds).length) {
      uni.showToast({
        title: '请选择要下载的图片',
        icon: 'none',
      });
      return;
    }
    const dwImgList = ref<string[]>([]);
    apiData.value.forEach((v: PhotoListResult) => {
      if (checkedIds.value.includes(v.id)) {
        dwImgList.value.push(v.url);
      }
    });
    downloadFiles(unref(dwImgList));
    settingIn.value = false;
  };
  // 批量删除
  const batchDeleteImg = () => {
    if (!unref(checkedIds).length) {
      uni.showToast({
        title: '请选择要删除的图片',
        icon: 'none',
      });
      return;
    }
    uni.showModal({
      title: '确认删除照片?',
      content: `照片删除后, 将无法再恢复`,
      success: async ({ confirm }) => {
        if (confirm) {
          await delBatchPhoto(unref(checkedIds));
          refresh?.();
          settingIn.value = false;
        }
      },
    });
  };

  // 打开分享
  const openShare = () => {
    showSharePopup.value = true;
  };

  onShareAppMessage(() => ({}));

  // 跳转相册设置页面
  const goAddPhotos = () => {
    navigateTo({
      name: 'addPhotos',
      options: {
        id: unref(id),
        callback: async () => {
          await __init();
          setShareOptions();
        },
      },
    });
  };

  // 预览图片 || 勾选图片
  const isPreview = ref<Boolean>(false);
  function previewPhoto(item: BatchUpImageData) {
    if (unref(settingIn)) {
      if (checkedIds.value.includes(item.id as number)) {
        checkedIds.value = checkedIds.value.filter((v) => v !== item.id);
      } else {
        checkedIds.value.push(item.id as number);
      }
    } else {
      const urls = apiData.value.map((v) => v.url);
      wx.previewImage({
        urls,
        current: item.url,
        showmenu: true,
        success: function () {
          isPreview.value = true;
        },
      });
    }
  }

  // 修改相册封面
  const upCoverImg = () => {
    navigateTo({
      name: 'addPhotos',
      options: {
        id: unref(id),
        openUpCoverImg: true, // 直接打开更改封面弹窗
        callback: async () => {
          await __init();
          setShareOptions();
        },
      },
    });
  };

  // 编辑标题 || 编辑描述
  const editNameIn = ref(false);
  const oldName = ref<string>('');
  const editDescIn = ref(false);
  const oldDesc = ref<string>('');

  function toggleEditName() {
    if (editNameIn.value) {
      editNameIn.value = false;
    } else {
      oldName.value = unref(photoAlbumInfo).name;
      editNameIn.value = true;
    }
  }
  function toggleEditDesc() {
    if (editDescIn.value) {
      editDescIn.value = false;
    } else {
      oldDesc.value = unref(photoAlbumInfo).desc;
      editDescIn.value = true;
    }
  }
  async function confirmEditName(e: any) {
    const { value } = e.detail;
    toggleEditName();
    if (!value || unref(oldName) === value) return; // 为空 || 未改变
    photoAlbumInfo.value.name = value;
    await modifyPhotoAlbum(unref(photoAlbumInfo));
    setShareOptions();
    Toast('修改成功');
  }
  async function confirmEditDesc(e: any) {
    const { value } = e.detail;
    toggleEditDesc();
    if (!value || unref(oldDesc) === value) return; // 为空 || 未改变
    photoAlbumInfo.value.desc = value;
    await modifyPhotoAlbum(unref(photoAlbumInfo));
    Toast('修改成功');
  }

  // 数字转整数 如 10000 转为1万
  const formatNumber = (num: number | string) => {
    num = Number(num);
    if (num == 0 || (num > 0 && num < 10000)) {
      return num + '';
    } else {
      return (num / 10000).toFixed(2) + '万';
    }
  };
</script>

<style lang="scss" scoped>
  .topTips {
    background-color: #fff;
    line-height: 60rpx;
    color: #b47026;
    text-align: center;
    width: 100%;
    font-size: 24rpx;
  }
  .imageBox {
    width: 750rpx;
    position: relative;
    .topTag {
      background-color: #d0f7ff;
      position: absolute;
      z-index: 9;
      color: #2878ff;
      top: 20rpx;
      right: 20rpx;
      border-radius: 10rpx;
    }
  }
  .timesBox {
    color: #aaabab;
  }
  .slotBox {
    width: 490rpx;
    display: flex;
    align-items: center;
  }
  .imgList {
    flex-wrap: wrap;
    .forImageBox {
      width: 345rpx;
      height: 345rpx;
      overflow: hidden;
      position: relative;
      flex-shrink: 0;
      .checkedBox {
        position: absolute;
        right: 20rpx;
        top: 20rpx;
      }
    }
  }

  .textBox {
    display: flex;
    justify-content: space-between;
    .editText {
      flex-shrink: 0;
      background-color: #e5efff;
      border-radius: 6rpx;
      color: #808080;
      padding: 0 10rpx;
      display: inline-block;
      line-height: 32rpx;
      margin-left: 12rpx;
      height: 32rpx;
      font-weight: 400;
    }
  }
</style>
